py-spy 的用法
py-spy 的用法
py-spy 命令概览
版本: 0.4.0
用途: Python 程序的采样分析器
| 子命令 | 说明 |
|---|---|
record |
记录堆栈轨迹信息,生成火焰图、speedscope 或原始文件 |
top |
以类 top 视图显示消耗 CPU 的函数 |
dump |
将目标程序的堆栈轨迹输出到 stdout |
help |
打印帮助信息 |
top 子命令
用途:以类 top 视图显示消耗 CPU 的函数
| 选项 | 默认值 | 说明 |
|---|---|---|
-p, --pid <pid> |
无 | 要监控的正在运行的 Python 进程 PID |
-r, --rate <rate> |
100 | 每秒采集的样本数 |
-s, --subprocesses |
无 | 分析原进程的子进程 |
--full-filenames |
无 | 显示完整的 Python 文件名,而非只显示包名部分 |
-g, --gil |
无 | 仅包含持有 GIL 的轨迹 |
-i, --idle |
无 | 包含空闲线程的堆栈轨迹 |
--delay <seconds> |
1.0 | top 刷新间隔(秒) |
-n, --native |
无 | 收集来自 Cython、C 或 C++ 编写的原生扩展的堆栈轨迹 |
--nonblocking |
无 | 采样时不暂停 Python 进程。此选项可降低采样对性能的影响,但可能导致结果不准确 |
-h, --help |
无 | 打印帮助信息 |
record 子命令
用途:记录堆栈轨迹信息,生成火焰图、speedscope 或原始文件
| 选项 | 默认值 | 说明 |
|---|---|---|
-p, --pid <pid> |
无 | 要记录的正在运行的 Python 进程 PID |
--full-filenames |
无 | 显示完整的 Python 文件名,而非只显示包名部分 |
-o, --output <filename> |
无 | 输出文件名 |
-f, --format <format> |
flamegraph | 输出文件格式(可选:flamegraph, raw, speedscope, chrometrace) |
-d, --duration <duration> |
无限制 | 采样的总秒数 |
-r, --rate <rate> |
100 | 每秒采集的样本数 |
-s, --subprocesses |
无 | 分析原进程的子进程 |
-F, --function |
无 | 按函数的首行号聚合样本,而非当前行号 |
--nolineno |
无 | 不显示行号 |
-t, --threads |
无 | 在输出中显示线程 ID |
-g, --gil |
无 | 仅包含持有 GIL 的轨迹 |
-i, --idle |
无 | 包含空闲线程的堆栈轨迹 |
-n, --native |
无 | 收集来自 Cython、C 或 C++ 编写的原生扩展的堆栈轨迹 |
--nonblocking |
无 | 采样时不暂停 Python 进程。此选项可降低采样对性能的影响,但可能导致结果不准确 |
-h, --help |
无 | 打印帮助信息 |
基础监控命令
1. 监控运行中的 Python 进程
# 查看 PID 为 12345 的 Python 进程的 CPU 使用情况(类似 top 命令)
sudo py-spy top -p 12345
# 每 2 秒刷新一次
sudo py-spy top -p 12345 --delay 2
2. 从启动开始监控 Python 程序
# 启动 Python 脚本并实时监控
sudo py-spy top -- python my_script.py arg1 arg2
# 监控 Django 开发服务器
sudo py-spy top -- python manage.py runserver
3. 生成性能火焰图
# 对运行中的进程采样 30 秒,生成火焰图
sudo py-spy record -p 12345 -d 30 -o flamegraph.svg
# 采样 10 秒,使用 speedscope 格式(适合 Web 交互式分析)
sudo py-spy record -p 12345 -d 10 -f speedscope -o profile.speedscope.json
4. 分析完整调用链(包括 C 扩展)
# 包含 Python 和 C/C++/Cython 扩展的堆栈
sudo py-spy record -p 12345 --native -o profile.svg
# 包含子进程分析
sudo py-spy record -p 12345 -s --native -o profile.svg
高级分析命令
5. 分析特定时间段的性能
# 高频率采样(500Hz),持续 5 秒
sudo py-spy record -p 12345 -r 500 -d 5 -o high_freq.svg
# 采样 1 分钟,按函数聚合而非行号
sudo py-spy record -p 12345 -d 60 -F -o by_function.svg
6. GIL 竞争分析
# 只显示持有 GIL 的调用堆栈(分析 GIL 竞争)
sudo py-spy top -p 12345 -g
# 记录 GIL 持有者的火焰图
sudo py-spy record -p 12345 -g -o gil_profile.svg
7. 线程分析
# 显示所有线程(包括空闲线程)
sudo py-spy top -p 12345 -i
# 火焰图中区分不同线程
sudo py-spy record -p 12345 -t -o threads.svg
8. 生产环境友好命令
# 使用非阻塞模式,减少对生产服务的影响
sudo py-spy record -p 12345 --nonblocking -d 60 -o prod_profile.svg
# 后台运行并输出到文件
sudo py-spy record -p 12345 -d 120 -o /tmp/profile_$(date +%Y%m%d_%H%M%S).svg &
实用组合命令
9. 查找性能瓶颈
# 监控并实时查看最耗时的函数
sudo py-spy top -p 12345 --full-filenames
# 生成详细调用链火焰图
sudo py-spy record -p 12345 --full-filenames --native -o detailed.svg
10. 调试命令
# 快速查看进程当前堆栈
sudo py-spy dump -p 12345
# 监控 Flask/Django 请求处理
sudo py-spy top -- python app.py
# 然后在浏览器访问应用,观察 CPU 使用变化
容器环境使用
# 在 Docker 容器内运行
docker exec -it <container_id> py-spy top -p 1
# 从宿主机监控容器进程
sudo py-spy top -p $(pgrep -f "python my_app")
常用参数组合总结
| 场景 | 推荐命令 |
|---|---|
| 快速查看性能热点 | sudo py-spy top -p <PID> |
| 生成火焰图报告 | sudo py-spy record -p <PID> -d 30 -o profile.svg |
| 分析包含 C 扩展 | sudo py-spy record -p <PID> --native -o profile.svg |
| 生产环境采样 | sudo py-spy record -p <PID> --nonblocking -d 60 -o profile.svg |
| 分析 GIL 竞争 | sudo py-spy top -p <PID> -g |
| 详细调用链分析 | sudo py-spy record -p <PID> --full-filenames --native -o detailed.svg |
注意事项:
- 通常需要
sudo权限 - 采样时间不宜过短(建议至少 10-30 秒)
- 生产环境使用
--nonblocking减少影响 - 分析完成后用浏览器打开
.svg文件查看火焰图